package robot;

import java.util.Collection;
import java.util.List;

import launcher.RobotLauncher;
import robocode.AdvancedRobot;
import robocode.DeathEvent;
import robocode.HitByBulletEvent;
import robocode.HitRobotEvent;
import robocode.HitWallEvent;
import robocode.ScannedRobotEvent;
import service.ServiceConstants;

import com.agentfactory.logic.lang.FOS;
import com.agentfactory.platform.core.IAgent;
import com.agentfactory.platform.core.IAgentContainer;


public class RobotAgent extends AdvancedRobot{

	public List<FOS> percepts;
	
	public double distance, distanceOld;
	public double turnAngle, turnAngleOld;
	public double gunAngle, gunAngleOld;
	public double radarAngle, radarAngleOld;
	
	public double power;
	public boolean openFire;
	
	public RobotAgent() {

		RobotLauncher.roboService.addRobotAgent(this);
		
		distance = distanceOld = 0;
		turnAngle = turnAngleOld = 0;
		gunAngle = gunAngleOld = 0;
		radarAngle = radarAngleOld = 0;
		
		power = 0;
		openFire = false;
		
		IAgentContainer aContainer = RobotLauncher.platform.getAgentContainer();
		IAgent[] aArray = aContainer.agents();
		Boolean temp = true;
		int i = 0;
		Collection<IAgent> aBound = RobotLauncher.roboService.getBoundAgents();
		while(temp){
			if(!aBound.contains(aArray[i])){
				aArray[i].bindToPlatformService(ServiceConstants.SERVICE_NAME);
				percepts = RobotLauncher.roboService.mapAgentToPercepts.get(aArray[i].getName());
				System.out.println("Robot bound to agent " + aArray[i].getName());
				temp = false;
			}
			i++;
			if(i == aArray.length) temp = false;
		}
	}

	public void run() {
		double distanceRemain, gunRemain, radarRemain, turnRemain;
		double gunHeading, shortAngle;
		while(!percepts.contains(new FOS("robot(off)"))){
			if(!percepts.contains(new FOS("robot(on)"))){
				percepts.add(new FOS("robot(on)"));
			}
			
			distanceRemain = getDistanceRemaining();
			// Stop
			if(distance != distanceOld){
				setAhead(distance);
				distanceOld = distance;
			}else{
				distance = distanceRemain;
				distanceOld = distance;
			}
			
			turnRemain = getTurnRemaining();
			if(turnAngle != turnAngleOld){
				setTurnLeft(turnAngle);
				turnAngleOld = turnAngle;
			}else{
				turnAngle = turnRemain;
				turnAngleOld = turnAngle;
			}
			
			gunHeading = getGunHeading();
			shortAngle = gunAngle - gunHeading;
			if(shortAngle > 180) shortAngle = shortAngle - 360;
			if(shortAngle < -180) shortAngle = shortAngle + 360;
			
			gunRemain = getGunTurnRemaining();
			if(gunAngle != gunAngleOld){
				setTurnGunRight(shortAngle);
				gunAngleOld = gunAngle;
			}else{
				gunAngle = gunRemain;
				gunAngleOld = gunAngle;
			}
			
			radarRemain = getRadarTurnRemaining();
			if(radarAngle != radarAngleOld){
				setTurnRadarLeft(radarAngle);
				radarAngleOld = radarAngle;
			}else{
				radarAngle = radarRemain;
				radarAngleOld = radarAngle;
			}
			
			if(openFire) this.setFire(power);
			execute();
		}
	}

	@Override
	public void onScannedRobot(ScannedRobotEvent e) {
		double absAngle;
		
		absAngle = e.getBearing() + this.getHeading(); //e.getHeading();
		percepts.add(new FOS("scan(" + absAngle + "," + e.getDistance() + "," + e.getHeading() + "," + e.getVelocity() + "," + e.getName() + ")"));
	}

	@Override
	public void onHitByBullet(HitByBulletEvent e) {
		percepts.add(new FOS("hit(" + e.getBearing() + "," + e.getName() + ")"));
		//stop();
		//angle = 0;
		
	}
	
	@Override
	public void onHitRobot(HitRobotEvent e) {
		percepts.add(new FOS("hitRobot(" + e.getBearing() + "," + e.getName() + "," + e.isMyFault() + ")"));
	}

	@Override
	public void onHitWall(HitWallEvent e) {
		percepts.add(new FOS("hitWall(" + e.getBearing() + ")"));
	}

	@Override
	public void onDeath(DeathEvent e) {
		percepts.add(new FOS("robot(off)"));
	}
}
